package com.girant.service.querybuilder;
import com.girant.entity.Material;
import com.girant.service.util.SearchUtils;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.stereotype.Component;
/**
 * 物料查询构建器
 * 职责：专门构建ES查询条件（中文、拼音、编号、规格等多维度）
 */
@Component
public class DefineQueryBuilder {

    public BoolQueryBuilder buildQuery(String keyword) {


         BoolQueryBuilder rootQuery = QueryBuilders.boolQuery();
        String[] subKeywords = keyword.split("\\s+|　+"); //拆分多关键词


        // 处理子关键词（中文、拼音、编号、大类、细类）
        for (String subKw : subKeywords) {
            if (subKw.trim().isEmpty()) continue;
            addMainQueries(subKw,rootQuery);
            System.out.println(subKw);
        }

        // 处理全局关键词（规格、别名）
        if (!keyword.isEmpty()) {
            addSpecsQueries(keyword,rootQuery);
        }

        return rootQuery;
    }

    /**
     * 处理子关键词的查询条件（中文、拼音、编号）
     */
    private BoolQueryBuilder addMainQueries(String sub, BoolQueryBuilder rootQuery) {
        // 提取子关键词成分
        String chinesePart = SearchUtils.extractChinese(sub);
        String pinyinPart = SearchUtils.extractPinyin(sub);
        String codePart = SearchUtils.extractCode(sub);

        //----------------------------- 1.物料名称中文查询---------------------------------------------------------------
        if (!chinesePart.isEmpty()) {
            rootQuery.should(QueryBuilders.termQuery("material_name.keyword", chinesePart)
                    .boost(20.0f)); //对 “物料名” 字段（material_name）进行精确匹配

            rootQuery.should(QueryBuilders.wildcardQuery("material_name", "*" + chinesePart + "*")
                    .boost(13.0f));//通配符查询

            rootQuery.should(QueryBuilders.matchQuery("material_name", chinesePart)
                    .analyzer("ik_max_word")
                    .boost( 12.0f));//中文分词查询
        }

        // -------------------------------1.2. 物料大类中文查询------------------------------------------------------------

        // 6.1 大类中文查询（重复词场景提高权重）
        rootQuery.should (QueryBuilders.termQuery ("material_type.keyword", chinesePart)
                .boost ( 7.0f));
        rootQuery.should (QueryBuilders.matchPhraseQuery ("material_type", chinesePart)
                .boost (30.0f));
        // -------------------------------1.3. 物料细类中文查询------------------------------------------------------------
        rootQuery.should (QueryBuilders.termQuery ("material_category.keyword", chinesePart)
                .boost (4.5f));// 对 “物料细类” 字段（material_category）进行精确匹配
        rootQuery.should (QueryBuilders.matchQuery ("material_category", chinesePart)
                .analyzer ("ik_max_word")
                .boost (3.5f));// 对 “物料细类” 字段进行中文分词匹配

        //--------------------------------2. 物料名称拼音查询（新增权重平衡逻辑）----------------------------------------------
        if (!pinyinPart.isEmpty()) {
            // 物料名称拼音查询（重复词场景降低权重）
            rootQuery.should(QueryBuilders.termQuery("material_name.pinyin.keyword", pinyinPart)
                    .boost( 10.0f));
            rootQuery.should(QueryBuilders.wildcardQuery("material_name.pinyin", "*" + pinyinPart + "*")
                    .boost( 8.0f));// 通配符匹配
            rootQuery.should(QueryBuilders.matchQuery("material_name.pinyin", pinyinPart)
                    .fuzziness(Fuzziness.ZERO)
                    .boost(8.0f));//分词查询
        }
        // ---------------------------------2.2 物料大类拼音查询（重复词场景提高权重）-----------------------------------------
        rootQuery.should (QueryBuilders.termQuery ("material_type.pinyin.keyword", pinyinPart)
                .boost (15.0f));// 对 “物料大类” 的拼音字段（material_type.pinyin）进行精确匹配

        rootQuery.should (QueryBuilders.matchQuery ("material_type.pinyin", pinyinPart)
                .fuzziness (Fuzziness.ZERO)
                .boost (15.0f));// 对 “物料大类” 的拼音字段进行分词匹配

        // ------------------------------------2.3. 物料细类拼音查询-------------------------------------------------------
        rootQuery.should (QueryBuilders.termQuery ("material_category.pinyin.keyword", pinyinPart) //不进行分词
                .boost (13.0f));// 对 “物料细类” 的拼音字段（material_category.pinyin）进行精确匹配
        rootQuery.should (QueryBuilders.wildcardQuery ("material_category.pinyin", "" + pinyinPart + "")
                .boost (13.5f));    // 对 “物料细类” 的拼音字段进行通配符模糊匹配
        rootQuery.should (QueryBuilders.matchQuery ("material_category.pinyin", pinyinPart)
                .fuzziness (Fuzziness.ZERO)
                .boost (12.0f));// 对 “物料细类” 的拼音字段进行分词匹配

        // ---------------------------------------2.4 规格拼音查询--------------------------------------------------------
        rootQuery.should (QueryBuilders.termQuery ("material_specs.pinyin.keyword", pinyinPart)
                .boost (12.5f));// 对 “规格型号” 的拼音字段（material_specs.pinyin）进行精确匹配
        rootQuery.should (QueryBuilders.matchQuery ("material_specs.pinyin", pinyinPart)
                .fuzziness (Fuzziness.ZERO)// 对 “规格型号” 的拼音字段进行分词匹配
                .boost (8.0f));
        // ------------------------------------------3. 编号查询（保持原有逻辑）---------------------------------------------
        if (!codePart.isEmpty()) {
            rootQuery.should(QueryBuilders.termQuery("material_code.keyword", codePart)
                    .boost(50.0f));
            rootQuery.should(QueryBuilders.prefixQuery("material_code.keyword", codePart)
                    .boost(55.0f));
            rootQuery.should(QueryBuilders.wildcardQuery("material_code.keyword", "*" + codePart)
                    .boost(25.5f));
            rootQuery.should(QueryBuilders.wildcardQuery("material_code.keyword", codePart + "-*")
                    .boost(65.0f));
            rootQuery.should(QueryBuilders.wildcardQuery("material_code.keyword", "*" + codePart + "*")
                    .boost(60.0f));
        }
        return rootQuery;
    }

    /**
     * 处理全局关键词的查询条件（规格、别名、大类等）
     */
    private void addSpecsQueries(String keyword, BoolQueryBuilder rootQuery) {
       // keyword = "规格*123?45"   "规格\*123\?45"
        String escapedKeyword = SearchUtils.escapeWildcards(keyword);
        // 4. 规格型号中文查询
        //------------------------------------- 4.1 规格中文查询----------------------------------------------------------
        rootQuery.should(QueryBuilders.termQuery("material_specs.keyword", keyword)
                .boost(8.0f));//对 “规格型号” 字段（material_specs）进行精确匹配

        if (keyword.contains("**")) {
            rootQuery.should(QueryBuilders.matchPhraseQuery("material_specs", keyword)
                    .boost(8.0f));//当关键词包含**时，对 “规格型号” 字段进行短语匹配
        }

        rootQuery.should(QueryBuilders.wildcardQuery("material_specs", "*" + escapedKeyword + "*")
                .boost(12.0f));//对 “规格型号” 字段进行通配符模糊匹配
        rootQuery.should(QueryBuilders.matchQuery("material_specs", keyword)
                .analyzer("ik_max_word")
                .boost(12.0f));//对 “规格型号” 字段进行分词匹配（中文分词）
        // ------------------------------------5. 物料别名查询------------------------------------------------------------
        rootQuery.should (QueryBuilders.termQuery ("material_alias.keyword", keyword)
                .boost (15.0f)); // 对 “物料别名” 字段（material_alias）进行精确匹配
        rootQuery.should (QueryBuilders.wildcardQuery ("material_alias", "" + escapedKeyword + "")
                .boost (10.0f));// 对 “物料别名” 字段进行通配符模糊匹配
        rootQuery.should (QueryBuilders.matchQuery ("material_alias", keyword)
                .analyzer ("ik_max_word")// 对 “物料别名” 字段进行中文分词匹配
                .boost (9.0f));
    }
}